<?php

namespace common\logics\order\handle;

use Yii;
use yii\db\Exception;
use common\models\shop\ShopOrder;
use common\models\shop\ShopOrderGoods;
use common\models\shop\ShopOrderCoupon;
use common\models\user\UserCoupon;
use common\logics\trade\CancelTradeHandleLogic;
use common\logics\order\OrderUnifiedLogic;
use common\logics\order\RecordOrderLog;

/**
 * 订单取消模型
 * 
 * @author emhome<emhome@163.com>
 * @since 2.0
 */
class OrderCancelHandle extends OrderBaseHandle {

    /**
     * @var string 统一订单模型基类
     */
    public $modelClass = OrderUnifiedLogic::class;

    /**
     * @var string 订单操作类型
     */
    public $handle = parent::HANDLE_CANCEL;

    /**
     * 取消订单
     * @return OrderUnifiedLogic
     * @throws Exception
     */
    protected function transactCancel() {
        $model = $this->getModel();
        $model->status = $model::STATUS_CANCEL;
        if (!$model->save()) {
            throw new Exception('订单取消失败，' . $model->getErrorMsg());
        }

        //取消统一订单下的商城订单
        $orders = $model->orders;
        foreach ($orders as $order) {
            $order->status = ShopOrder::STATUS_CANCEL;
            if (!$order->save()) {
                throw new Exception('订单取消失败，' . $order->getErrorMsg());
            }
            //记录订单日志
            RecordOrderLog::safeRecord($order, $this->reason, $this->operator);
        }

        //回收库存
        /* @var $orderGoods ShopOrderGoods[] */
        $orderGoods = $model->goods;
        foreach ($orderGoods as $goods) {
            $sku = $goods->goods;
            $sku->stock += $goods->goods_number;
            if ($sku->total < $sku->stock) {
                $sku->total = $sku->stock;
                $sku->shelf = $sku->stock;
            }
            if (!$sku->save()) {
                throw new Exception('库存回收失败，' . $sku->getErrorMsg());
            }
            $goods->status = ShopOrderGoods::STATUS_RETURN;
            if (!$goods->save()) {
                throw new Exception('订单商品取消失败，' . $goods->getErrorMsg());
            }
        }

        //回收用户使用的优惠券
        $orderCoupons = $model->coupons;
        foreach ($orderCoupons as $orderCoupon) {
            $userCoupon = $orderCoupon->userCoupon;
            if (!$userCoupon) {
                continue;
            }
            $userCoupon->model = '';
            $userCoupon->model_id = 0;
            $userCoupon->usage_time = 0;
            $userCoupon->status = UserCoupon::STATUS_DEFAULT;
            if (!$userCoupon->save()) {
                throw new Exception('用户优惠券退回失败，' . $userCoupon->getErrorMsg());
            }
            $orderCoupon->status = ShopOrderCoupon::STATUS_REFUND;
            $orderCoupon->coupon_refund_at = time();
            if (!$orderCoupon->save()) {
                throw new Exception('订单优惠券退回失败，' . $orderCoupon->getErrorMsg());
            }
        }

        //取消统一订单下的所有未支付的历史交易        
        $cancelTradeHandler = new CancelTradeHandleLogic();
        $cancelTradeHandler->bizno = $model->order_no;
        $cancelTradeHandler->reason = '订单过期系统自动取消交易';
        if (!$cancelTradeHandler->cancel()) {
            throw new Exception('订单取消失败，取消交易处理失败。' . $order->getErrorMsg());
        }
        return $model;
    }

}
